package com.aviatorscript.avitorscriptmust.controller;

import com.aviatorscript.avitorscriptmust.common.Result;
import com.aviatorscript.avitorscriptmust.dto.ValidationConfigDTO;
import com.aviatorscript.avitorscriptmust.entity.FieldValidationConfig;
import com.aviatorscript.avitorscriptmust.service.FieldValidationConfigService;
import com.aviatorscript.avitorscriptmust.cache.AviatorValidationCacheManager;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 校验规则配置管理Controller
 * 提供CRUD接口用于管理AviatorScript校验规则
 *
 * @author system
 */
@RestController
@RequestMapping("/api/validation/config")
@Slf4j
public class ValidationConfigController {
    
    @Autowired
    private FieldValidationConfigService validationConfigService;
    
    @Autowired
    private AviatorValidationCacheManager cacheManager;
    
    /**
     * 创建校验规则
     */
    @PostMapping
    public Result<Long> createValidationRule(@RequestBody ValidationConfigDTO dto) {
        log.info("创建校验规则请求: {}", dto.getRuleName());
        
        try {
            // 手动校验必填参数
            String validationError = validateDto(dto);
            if (validationError != null) {
                return Result.validateError(validationError);
            }
            
            Long configId = validationConfigService.createValidationRule(dto);
            return Result.success(configId, "校验规则创建成功");
            
        } catch (Exception e) {
            log.error("创建校验规则失败", e);
            return Result.error("创建校验规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新校验规则
     */
    @PutMapping("/{id}")
    public Result<Boolean> updateValidationRule(@PathVariable Long id, @RequestBody ValidationConfigDTO dto) {
        log.info("更新校验规则请求: id={}, ruleName={}", id, dto.getRuleName());
        
        try {
            // 手动校验必填参数
            String validationError = validateDto(dto);
            if (validationError != null) {
                return Result.validateError(validationError);
            }
            
            boolean success = validationConfigService.updateValidationRule(id, dto);
            return Result.success(success, "校验规则更新成功");
            
        } catch (Exception e) {
            log.error("更新校验规则失败: id={}", id, e);
            return Result.error("更新校验规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除校验规则
     */
    @DeleteMapping("/{id}")
    public Result<Boolean> deleteValidationRule(@PathVariable Long id) {
        log.info("删除校验规则请求: id={}", id);
        
        try {
            boolean success = validationConfigService.deleteValidationRule(id);
            return Result.success(success, "校验规则删除成功");
            
        } catch (Exception e) {
            log.error("删除校验规则失败: id={}", id, e);
            return Result.error("删除校验规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 启用/禁用校验规则
     */
    @PutMapping("/{id}/status")
    public Result<Boolean> updateValidationRuleStatus(@PathVariable Long id, @RequestParam Integer status) {
        log.info("更新校验规则状态请求: id={}, status={}", id, status);
        
        try {
            if (status == null || (status != 0 && status != 1)) {
                return Result.validateError("状态值必须为0（禁用）或1（启用）");
            }
            
            boolean success = validationConfigService.updateStatus(id, status);
            return Result.success(success, "校验规则状态更新成功");
            
        } catch (Exception e) {
            log.error("更新校验规则状态失败: id={}, status={}", id, status, e);
            return Result.error("更新校验规则状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询校验规则详情
     */
    @GetMapping("/{id}")
    public Result<ValidationConfigDTO> getValidationRuleById(@PathVariable Long id) {
        try {
            FieldValidationConfig config = validationConfigService.getById(id);
            if (config == null) {
                return Result.error(404, "校验规则不存在");
            }
            
            ValidationConfigDTO dto = new ValidationConfigDTO();
            BeanUtils.copyProperties(config, dto);
            
            return Result.success(dto);
            
        } catch (Exception e) {
            log.error("查询校验规则详情失败: id={}", id, e);
            return Result.error("查询校验规则详情失败: " + e.getMessage());
        }
    }
    
    /**
     * 分页查询校验规则列表
     */
    @GetMapping("/page")
    public Result<Page<FieldValidationConfig>> getValidationRulePage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String className,
            @RequestParam(required = false) String ruleName,
            @RequestParam(required = false) Integer status) {
        
        try {
            Page<FieldValidationConfig> page = new Page<>(current, size);
            
            LambdaQueryWrapper<FieldValidationConfig> queryWrapper = new LambdaQueryWrapper<>();
            if (StringUtils.hasText(className)) {
                queryWrapper.like(FieldValidationConfig::getClassName, className);
            }
            if (StringUtils.hasText(ruleName)) {
                queryWrapper.like(FieldValidationConfig::getRuleName, ruleName);
            }
            if (status != null) {
                queryWrapper.eq(FieldValidationConfig::getStatus, status);
            }
            queryWrapper.orderByDesc(FieldValidationConfig::getCreateTime);
            
            Page<FieldValidationConfig> resultPage = validationConfigService.page(page, queryWrapper);
            return Result.success(resultPage);
            
        } catch (Exception e) {
            log.error("分页查询校验规则失败", e);
            return Result.error("分页查询校验规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据类名查询校验规则列表
     */
    @GetMapping("/class/{className}")
    public Result<List<FieldValidationConfig>> getValidationRulesByClassName(@PathVariable String className) {
        try {
            List<FieldValidationConfig> rules = validationConfigService.getEnabledRulesByClassName(className);
            return Result.success(rules);
            
        } catch (Exception e) {
            log.error("根据类名查询校验规则失败: className={}", className, e);
            return Result.error("查询校验规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 校验脚本语法
     */
    @PostMapping("/validate-script")
    public Result<String> validateScript(@RequestBody Map<String, String> request) {
        try {
            String scriptContent = request.get("scriptContent");
            if (!StringUtils.hasText(scriptContent)) {
                return Result.validateError("脚本内容不能为空");
            }
            
            String validationResult = validationConfigService.validateScript(scriptContent);
            
            if ("脚本语法正确".equals(validationResult)) {
                return Result.success(validationResult, "脚本语法校验通过");
            } else {
                return Result.validateError(validationResult);
            }
            
        } catch (Exception e) {
            log.error("校验脚本语法失败", e);
            return Result.error("校验脚本语法失败: " + e.getMessage());
        }
    }
    
    /**
     * 刷新指定类的缓存
     */
    @PostMapping("/cache/refresh/{className}")
    public Result<Void> refreshCache(@PathVariable String className) {
        log.info("手动刷新缓存请求: className={}", className);
        
        try {
            cacheManager.refreshCache(className);
            return Result.success(null, "缓存刷新成功");
            
        } catch (Exception e) {
            log.error("刷新缓存失败: className={}", className, e);
            return Result.error("刷新缓存失败: " + e.getMessage());
        }
    }
    
    /**
     * 刷新所有缓存
     */
    @PostMapping("/cache/refresh-all")
    public Result<Void> refreshAllCache() {
        log.info("手动刷新所有缓存请求");
        
        try {
            cacheManager.refreshAllCache();
            return Result.success(null, "所有缓存刷新成功");
            
        } catch (Exception e) {
            log.error("刷新所有缓存失败", e);
            return Result.error("刷新所有缓存失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取缓存统计信息
     */
    @GetMapping("/cache/statistics")
    public Result<Map<String, Object>> getCacheStatistics() {
        try {
            Map<String, Object> statistics = cacheManager.getCacheStatistics();
            return Result.success(statistics);
            
        } catch (Exception e) {
            log.error("获取缓存统计信息失败", e);
            return Result.error("获取缓存统计信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取所有已缓存的类名
     */
    @GetMapping("/cache/classes")
    public Result<Set<String>> getCachedClassNames() {
        try {
            Set<String> classNames = cacheManager.getCachedClassNames();
            return Result.success(classNames);
            
        } catch (Exception e) {
            log.error("获取已缓存类名失败", e);
            return Result.error("获取已缓存类名失败: " + e.getMessage());
        }
    }
    
    /**
     * 手动校验DTO参数
     * 
     * @param dto 校验配置DTO
     * @return 错误信息，如果返回null表示校验通过
     */
    private String validateDto(ValidationConfigDTO dto) {
        if (!StringUtils.hasText(dto.getRuleName())) {
            return "规则名称不能为空";
        }
        if (!StringUtils.hasText(dto.getClassName())) {
            return "类名不能为空";
        }
        if (!StringUtils.hasText(dto.getFieldPath())) {
            return "字段路径不能为空";
        }
        if (!StringUtils.hasText(dto.getScriptContent())) {
            return "脚本内容不能为空";
        }
        if (!StringUtils.hasText(dto.getErrorMessage())) {
            return "错误信息不能为空";
        }
        if (dto.getPriority() == null) {
            return "优先级不能为空";
        }
        
        return null; // 校验通过
    }
} 